package com.junzhiit.nengji.cms.service.impl;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.ImageIcon;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.junzhiit.nengji.bo.WaterMarkBO;
import com.junzhiit.nengji.cms.service.WaterMarkService;
import com.junzhiit.nengji.cms.web.util.FileUtil;
import com.junzhiit.nengji.cms.web.util.ThumbnailsUtil;
import com.junzhiit.nengji.cms.web.util.aliyun.AliyunOSSClientUtil;
import com.junzhiit.nengji.cms.web.vo.ResultVO;
import com.junzhiit.nengji.cms.web.vo.WaterMarkVO;
import com.junzhiit.nengji.dao.ChainDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.model.enums.Is;

@Service
public class WaterMarkServiceImpl implements WaterMarkService {

	@Autowired
	SystemUserCacheDAO systemUserCacheDAO;

	@Autowired
	ChainDAO chainDAO;

	@Autowired
	ShopDAO shopDAO;

	@Value("${upload.temp}")
	private String tempPath;

	// 阿里云API的bucket名称
	@Value("${oss.backet.name}")
	private String backetName;

	@Value("${oss.url}")
	private String url;
	
	@Value("${upload.mall.promotion.poster}")
	private String posterPath;

	@Override
	public ResultVO addWaterMark(HttpServletResponse response, HttpServletRequest request, WaterMarkVO wmv) {
		ResultVO result = new ResultVO();
		WaterMarkBO wmb = new WaterMarkBO();
		BeanUtils.copyProperties(wmv, wmb);
		String fileName = null;
		String suffix = null;
		if (StringUtils.isNoneBlank(wmv.getFileName())) {
			suffix = wmv.getFileName().substring(wmv.getFileName().lastIndexOf("."));
			fileName = wmv.getFileName();
		} else {
			suffix = wmb.getSrcImg().substring(wmb.getSrcImg().lastIndexOf("."));
			fileName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
		}
		wmb.setTargetPath(tempPath + fileName);
		Map<String, String> map = waterMarkImg(wmb, suffix);
		if (wmb.getIsDownload() == Is.NO.toIntValue()) {
			try {
				AliyunOSSClientUtil.uploadObject2OSS(new FileInputStream(new File(wmb.getTargetPath())), fileName,
						backetName, tempPath);
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			map.put("fileName", fileName);
			result.setData(map);
		}
		if (wmb.getIsDownload() == Is.YES.toIntValue()) {
			FileUtil.download(request, response, wmb.getTargetPath());
		}
		return result;
	}

	private Map<String, String> waterMarkImg(WaterMarkBO wmb, String suffix) {
		Map<String, String> map = new HashMap<>();
		OutputStream os = null;
		String targetSrcImg;
		try {
			targetSrcImg = toScaleImg(wmb.getSrcImg(), suffix, wmb.getPmWidth(), wmb.getPmHeight(),wmb.getIsDownload(),wmb.getId());
			map.put("srcImg", targetSrcImg);
			Image srcImg = ImageIO.read(new File(tempPath + targetSrcImg));
			BufferedImage bufImg = new BufferedImage(srcImg.getWidth(null), srcImg.getHeight(null),
					BufferedImage.TYPE_INT_RGB);
			Graphics2D g = bufImg.createGraphics();
			g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
			g.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null), srcImg.getHeight(null), Image.SCALE_SMOOTH), 0,
					0, null);
			String targetIcon = toScaleImg(wmb.getIcon(), suffix, wmb.getWidthSize(), wmb.getHeightSize(),wmb.getIsDownload(),wmb.getId());
			map.put("icon", targetIcon);
			ImageIcon imgIcon = new ImageIcon(tempPath+targetIcon);
			Image img = imgIcon.getImage();
			g.rotate(Math.toRadians(wmb.getDegree()), wmb.getlLocation() + wmb.getWidthSize() / 2,
					wmb.gettLocation() + wmb.getHeightSize() / 2);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, wmb.getAlpha()));
			g.drawImage(img, wmb.getlLocation(), wmb.gettLocation(), null);
			g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
			g.dispose();
			os = new FileOutputStream(wmb.getTargetPath());
			ImageIO.write(bufImg, "JPG", os);
		} catch (IOException e) {
			e.printStackTrace();
		}
		return map;
	}

	private String toScaleImg(String sourceName, String suffix, Integer width, Integer height, Integer isDownload,String id)
			throws IOException {
		String middlePath=null;
		if(StringUtils.isNoneBlank(id)){
			middlePath=posterPath;
		}else{
			middlePath=tempPath;
		}
		String sourcePath = tempPath + sourceName;
		String targetName = UUID.randomUUID().toString().replaceAll("-", "") + suffix;
		String targetPath = tempPath + targetName;
		URL urlPath = new URL(url + middlePath + sourceName);
		HttpURLConnection conn = (HttpURLConnection) urlPath.openConnection();
		InputStream is = conn.getInputStream();
		File sourceFile = new File(sourcePath);
		saveFile(is, sourceFile);
		ThumbnailsUtil.toSize(sourcePath, tempPath, targetName, width, height);
		if (isDownload == Is.NO.toIntValue()) {
			AliyunOSSClientUtil.uploadObject2OSS(new FileInputStream(new File(targetPath)), targetName, backetName,tempPath);
		}
		return targetName;
	}

	public void saveFile(InputStream is, File targetPath) {
		FileOutputStream fos = null;
		File parentFile = targetPath.getParentFile();
		if (!parentFile.exists()) {
			parentFile.mkdirs();
		}
		try {
			fos = new FileOutputStream(targetPath);
			byte[] buff = new byte[1024 * 4];
			int len;
			while ((len = is.read(buff)) != -1) {
				fos.write(buff, 0, len);
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (is != null) {
					is.close();
				}
				if (fos != null) {
					fos.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
}
